package se.webbzon.boltzmann.game.object.portal;

import se.webbzon.boltzmann.game.switchable.Switchable;
import se.webbzon.boltzmann.sound.SoundUtils;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;

public abstract class AbstractDoor extends WorldStaticObject implements Switchable {
	
	// The speed of the door
	private final double doorSpeed;
	
	// Whatever the door is open
	private boolean open;
	
	// The open percentage level of the door (0.0 = closed, 1.0 = open)
	private double p;

	/*============================================================
	Constructor
	============================================================*/
	
	/** Creates a new abstract door with a given appearance.
	 * The door will be opened/closed in 15 steps. */
	public AbstractDoor(Appearance3D appearance) {
		this(appearance,15);
	}
	
	/** Creates a new abstract door with a given appearance and
	 * speed. The speed is defined as the number of steps to open
	 * and close the door. **/
	public AbstractDoor(Appearance3D appearance, int doorSpeed) {
		super(WorldObject.onStep, appearance);
		this.doorSpeed = 1 / (double) doorSpeed;
		p = 0;
		open = false;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** This method is invoked when the open percentage level is
	 * changed for the door. **/
	public abstract void onUpdate(double p);
	
	/** Opens the door. If the parameters "instant" is true then
	 * the door is opened instantly (in a single step). **/
	public void open(boolean instant) {
		setEnable(true,instant);
	}
	
	/** Closes the door. If the parameters "instant" is true then
	 * the door is closed instantly (in a single step). **/
	public void close(boolean instant) {
		setEnable(false,instant);
	}
	
	/** Returns true if the door is open. **/
	public boolean isOpen() {
		return isEnabled();
	}
	
	@Override public void onStep(WorldArea world) {
		if (open && p < 1) {
			p = Math.min(1, p + doorSpeed);
			onUpdate(p);
		} else if (!open && p > 0) {
			p = Math.max(0, p - doorSpeed);
			onUpdate(p);
		} 
		
	}

	@Override public void setEnable(boolean enable, boolean instant) {
		open = enable;
		if (instant) {
			p = open ? 1.0 : 0.0;
			onUpdate(p);
		} else if (enable) {
			SoundUtils.playSound("door_open");
		} else
			SoundUtils.playSound("door_close");
		
	}

	@Override public boolean isEnabled() {
		return open;
	}

}
